﻿using Authentication.Model.Interface;
using Authentication.Model.Model;
using Common.Contract;
using Common.Contract.Authentication.Record;
using Common.Contract.Authentication.Request;
using Common.Data.Repository.Enum;
using Common.Service.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Authentication.Core.ServiceCommand.ChangeDao
{
    public class UpdateChangeDaoRequestMultipleServiceCommand : ProviderServiceCommand<IProviderFactory, UpdateChangeDaoRequestRequest, ResponseRecord>
    {
        #region Private Properties

        public UserRecord CurrentUser;
        public List<ChangeDaoProduct> ListProduct;
        public List<Customers> ListCustomer;
        public List<string> ListCif;
        #endregion
        public UpdateChangeDaoRequestMultipleServiceCommand(IProviderFactory providers) : base(providers) { }
        protected override void Validate(UpdateChangeDaoRequestRequest request)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (!request.Header.ApplicationKey.HasValue || request.Header.ApplicationKey == Guid.Empty)
            {
                throw new ArgumentException("ApplicationKey must be set", "request");
            }
            if (request.Record == null)
            {
                throw new ArgumentException("Record must be set", "request");
            }
            if (request.CurrentUser == null)
            {
                throw new ArgumentException("Record must be set", "request");
            }
            else
            {
                CurrentUser = request.CurrentUser;
            }
        }

        protected override bool OnExecute(ResponseRecord response)
        {

            bool isSaved = false;
            string errorMessage = string.Empty;
            try
            {
                var record = Request.Record;
                var changeDaoRequest = new ChangeDaoRequest
                {
                    Pic = CurrentUser.UserName,
                    CreatedDate = DateTime.Now,
                    Reason = record.Reason,
                    UpdatedDate = DateTime.Now,
                    ReasonDescription = record.ReasonDescription,
                    Status = (int)StatusChangeDaoEnum.Request,
                    BranchCodeSme = CurrentUser.BranchCode,
                    IsDeviation = record.IsDeviation ? 1 : 0
                };
                bool checkCondition = CheckConditionRecord(out errorMessage, record);
                //bool checkCondition = true;
                if (checkCondition)
                {
                    ChangeDaoRequest savedUser = Providers.ChangeDao.SaveChangeDaoRequest(changeDaoRequest);
                    if (savedUser != null && Request.ListChangeDaoCif != null && Request.ListChangeDaoCif.Count > 0)
                    {
                        int changeDaoId = savedUser.Id;
                        var listCifCustomer = ListCustomer.Select(y => y.Cif);
                        var changeDaoCif = Request.ListChangeDaoCif.Select(x => new ChangeDaoCif
                        {
                            Cif = x.Cif,
                            NewDao = x.NewDao,
                            Pic = CurrentUser.UserName,
                            ChangeDaoId = changeDaoId,
                            IsInBranch = listCifCustomer.Contains(x.Cif) ? 1 : 0,
                            Status = x.IsApproved ? (int)StatusChangeDaoCifEnum.Request : (int)StatusChangeDaoCifEnum.Reject,
                        }).ToList();
                        isSaved = Providers.ChangeDao.SaveChangeDaoCifMultiple(Request.ListChangeDaoCif, changeDaoCif, ListProduct);
                    }
                    response.IsSuccess = isSaved;
                }
                else
                {
                    response.IsSuccess = checkCondition;
                    response.ErrorMessage = errorMessage;
                }
            }
            catch (Exception ex)
            {
                response.ErrorMessage = ex.Message;
                response.IsSuccess = false;
            }
            return response.IsSuccess;
        }

        private bool CheckConditionRecord(out string errorMessage, ChangeDaoRequestRecord record)
        {
            bool isChecked = true;
            var listDao = Request.ListChangeDaoCif.Select(x => x.NewDao).ToList();
            listDao = listDao.Distinct().ToList();
            errorMessage = string.Empty;
            List<Account> CheckDao = Providers.Users.CheckDaoAndBranch(listDao, CurrentUser);
            var query = from c in listDao
                        where !(from o in CheckDao
                                select o.Dao)
                                .Contains(c)
                        select c;
            if (query.Count() > 0)
            {
                errorMessage = string.Format("DAO code: {0} is not in your branch", string.Join(";", query.ToArray()));
                isChecked = false;
            }

            ListCif = Request.ListChangeDaoCif.Select(x => x.Cif).ToList();
            ListCustomer = Providers.Customer.RetrieveListCustomerByCifAndBranch(ListCif, CurrentUser.BranchId);

            ListProduct = Providers.ChangeDao.RetrieveListChangeDaoProductByCif(Request.ListChangeDaoCif, CurrentUser);
            ListProduct = (from x in ListProduct
                           join y in Request.ListChangeDaoCif on x.Cif equals y.Cif
                           where string.IsNullOrEmpty(x.Dao) || x.Dao != y.NewDao
                           select x).ToList();
            if (ListCustomer.Count == 0 && ListProduct.Count == 0)
            {
                errorMessage = string.Format("List cif: {0} don't have any info in your branch", string.Join(";", ListCif.ToArray()));
                isChecked = false;
            }

            //errorMessage = string.Empty;
            return isChecked;
        }
    }
}
